// ============================================
// 08 - 常见集合 (Common Collections)
// ============================================

/// Rust 标准库包含一些非常有用的集合数据结构
/// 不同于内建的数组和元组，这些集合指向的数据存储在堆上

// ==================== Vector ====================

/// Vector (动态数组)
/// Vec<T> 允许存储可变数量的值
pub fn vector_basics() {
    println!("\n=== Vector 基础 ===");
    
    // 创建新的 vector
    let v: Vec<i32> = Vec::new();
    println!("空 vector: {:?}", v);
    
    // 使用宏创建包含初始值的 vector
    let v = vec![1, 2, 3, 4, 5];
    println!("初始化的 vector: {:?}", v);
    
    // 添加元素
    let mut v = Vec::new();
    v.push(1);
    v.push(2);
    v.push(3);
    println!("添加元素后: {:?}", v);
}

/// 读取 vector 元素
pub fn reading_vector_elements() {
    println!("\n=== 读取 Vector 元素 ===");
    
    let v = vec![1, 2, 3, 4, 5];
    
    // 方法1: 使用索引
    let third = &v[2];
    println!("第三个元素: {}", third);
    
    // 方法2: 使用 get 方法
    match v.get(2) {
        Some(third) => println!("第三个元素: {}", third),
        None => println!("没有第三个元素"),
    }
    
    // 索引越界
    // let does_not_exist = &v[100]; // ❌ panic!
    
    // get 方法返回 Option，更安全
    match v.get(100) {
        Some(element) => println!("元素: {}", element),
        None => println!("索引超出范围"),
    }
}

/// 遍历 vector
pub fn iterating_over_vectors() {
    println!("\n=== 遍历 Vector ===");
    
    let v = vec![100, 32, 57];
    
    // 不可变引用遍历
    println!("遍历元素:");
    for i in &v {
        print!("{} ", i);
    }
    println!();
    
    // 可变引用遍历并修改
    let mut v = vec![100, 32, 57];
    for i in &mut v {
        *i += 50; // 解引用并修改
    }
    println!("修改后的 vector: {:?}", v);
    
    // 带索引遍历
    println!("带索引遍历:");
    for (i, value) in v.iter().enumerate() {
        println!("  索引 {}: {}", i, value);
    }
}

/// Vector 存储不同类型
/// 使用枚举存储多种类型
pub fn storing_multiple_types() {
    println!("\n=== 存储多种类型 ===");
    
    #[derive(Debug)]
    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }
    
    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Float(10.12),
        SpreadsheetCell::Text(String::from("blue")),
    ];
    
    println!("电子表格行: {:?}", row);
}

/// Vector 常用方法
pub fn vector_methods() {
    println!("\n=== Vector 方法 ===");
    
    let mut v = vec![1, 2, 3];
    
    // len() - 长度
    println!("长度: {}", v.len());
    
    // is_empty() - 是否为空
    println!("是否为空: {}", v.is_empty());
    
    // push() - 添加元素
    v.push(4);
    println!("push 后: {:?}", v);
    
    // pop() - 移除并返回最后一个元素
    let last = v.pop();
    println!("pop: {:?}, 剩余: {:?}", last, v);
    
    // insert() - 在指定位置插入
    v.insert(1, 99);
    println!("insert 后: {:?}", v);
    
    // remove() - 移除指定位置的元素
    let removed = v.remove(1);
    println!("remove: {}, 剩余: {:?}", removed, v);
    
    // clear() - 清空
    v.clear();
    println!("clear 后: {:?}", v);
}

// ==================== String ====================

/// String 字符串
/// String 是 UTF-8 编码的字符串类型
pub fn string_basics() {
    println!("\n=== String 基础 ===");
    
    // 创建新字符串
    let mut s = String::new();
    println!("空字符串: '{}'", s);
    
    // 从字符串字面量创建
    let s = "initial contents".to_string();
    println!("to_string: {}", s);
    
    let s = String::from("initial contents");
    println!("String::from: {}", s);
    
    // UTF-8 编码
    let hello = String::from("السلام عليكم");
    let hello = String::from("Dobrý den");
    let hello = String::from("Hello");
    let hello = String::from("שָׁלוֹם");
    let hello = String::from("नमस्ते");
    let hello = String::from("こんにちは");
    let hello = String::from("안녕하세요");
    let hello = String::from("你好");
    let hello = String::from("Olá");
    let hello = String::from("Здравствуйте");
    let hello = String::from("Hola");
    
    println!("支持 UTF-8: {}", hello);
}

/// 更新字符串
pub fn updating_strings() {
    println!("\n=== 更新字符串 ===");
    
    // push_str() - 附加字符串切片
    let mut s = String::from("foo");
    s.push_str("bar");
    println!("push_str: {}", s);
    
    // push() - 附加单个字符
    let mut s = String::from("lo");
    s.push('l');
    println!("push: {}", s);
    
    // + 运算符连接字符串
    let s1 = String::from("Hello, ");
    let s2 = String::from("world!");
    let s3 = s1 + &s2; // s1 被移动了，不能再使用
    println!("+ 运算符: {}", s3);
    
    // format! 宏
    let s1 = String::from("tic");
    let s2 = String::from("tac");
    let s3 = String::from("toe");
    let s = format!("{}-{}-{}", s1, s2, s3);
    println!("format!: {}", s);
}

/// 字符串索引
pub fn string_indexing() {
    println!("\n=== 字符串索引 ===");
    
    let s = String::from("hello");
    // let h = s[0]; // ❌ 错误: String 不支持索引
    
    println!("Rust 不支持字符串索引，因为:");
    println!("1. UTF-8 编码，一个字符可能占多个字节");
    println!("2. 索引操作应该是 O(1)，但 UTF-8 需要遍历");
    
    // 可以使用切片，但要小心
    let hello = "你好";
    let s = &hello[0..3]; // 一个中文字符占 3 字节
    println!("切片: {}", s);
    
    // 错误的切片会 panic
    // let s = &hello[0..1]; // ❌ panic: byte index not on char boundary
}

/// 遍历字符串
pub fn iterating_over_strings() {
    println!("\n=== 遍历字符串 ===");
    
    let s = String::from("你好");
    
    // 遍历字符
    println!("遍历字符:");
    for c in s.chars() {
        print!("{} ", c);
    }
    println!();
    
    // 遍历字节
    println!("遍历字节:");
    for b in s.bytes() {
        print!("{} ", b);
    }
    println!();
}

/// String 方法
pub fn string_methods() {
    println!("\n=== String 方法 ===");
    
    let s = String::from("  Hello, Rust!  ");
    
    // len() - 字节长度
    println!("字节长度: {}", s.len());
    
    // is_empty() - 是否为空
    println!("是否为空: {}", s.is_empty());
    
    // contains() - 包含子串
    println!("包含 'Rust': {}", s.contains("Rust"));
    
    // starts_with() / ends_with()
    println!("以 '  Hello' 开头: {}", s.starts_with("  Hello"));
    
    // replace() - 替换
    let replaced = s.replace("Rust", "World");
    println!("替换后: '{}'", replaced);
    
    // trim() - 去除首尾空白
    let trimmed = s.trim();
    println!("trim: '{}'", trimmed);
    
    // split() - 分割
    let parts: Vec<&str> = "a,b,c,d".split(',').collect();
    println!("split: {:?}", parts);
}

// ==================== HashMap ====================

use std::collections::HashMap;

/// HashMap 哈希映射
/// 存储键值对
pub fn hashmap_basics() {
    println!("\n=== HashMap 基础 ===");
    
    // 创建 HashMap
    let mut scores = HashMap::new();
    
    // 插入键值对
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
    
    println!("scores: {:?}", scores);
    
    // 使用 collect 创建
    let teams = vec![String::from("Blue"), String::from("Yellow")];
    let initial_scores = vec![10, 50];
    
    let scores: HashMap<_, _> = teams.into_iter()
        .zip(initial_scores.into_iter())
        .collect();
    
    println!("使用 collect: {:?}", scores);
}

/// 访问 HashMap 中的值
pub fn accessing_hashmap_values() {
    println!("\n=== 访问 HashMap 值 ===");
    
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);
    
    // 使用 get 方法
    let team_name = String::from("Blue");
    match scores.get(&team_name) {
        Some(score) => println!("{} 队得分: {}", team_name, score),
        None => println!("队伍不存在"),
    }
    
    // 遍历 HashMap
    println!("所有队伍得分:");
    for (key, value) in &scores {
        println!("  {}: {}", key, value);
    }
}

/// HashMap 和所有权
pub fn hashmap_and_ownership() {
    println!("\n=== HashMap 和所有权 ===");
    
    let field_name = String::from("Favorite color");
    let field_value = String::from("Blue");
    
    let mut map = HashMap::new();
    map.insert(field_name, field_value);
    // field_name 和 field_value 已被移动
    // println!("{}", field_name); // ❌ 错误
    
    println!("对于实现了 Copy 的类型，值会被复制");
    let key = 1;
    let value = 2;
    let mut map = HashMap::new();
    map.insert(key, value);
    println!("key 仍可用: {}", key);
}

/// 更新 HashMap
pub fn updating_hashmap() {
    println!("\n=== 更新 HashMap ===");
    
    let mut scores = HashMap::new();
    
    // 覆盖旧值
    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Blue"), 25);
    println!("覆盖: {:?}", scores);
    
    // 只在键不存在时插入
    scores.entry(String::from("Yellow")).or_insert(50);
    scores.entry(String::from("Blue")).or_insert(50);
    println!("or_insert: {:?}", scores);
    
    // 根据旧值更新
    let text = "hello world wonderful world";
    let mut map = HashMap::new();
    
    for word in text.split_whitespace() {
        let count = map.entry(word).or_insert(0);
        *count += 1;
    }
    
    println!("单词计数: {:?}", map);
}

/// HashMap 方法
pub fn hashmap_methods() {
    println!("\n=== HashMap 方法 ===");
    
    let mut map = HashMap::new();
    map.insert("a", 1);
    map.insert("b", 2);
    
    // len() - 大小
    println!("长度: {}", map.len());
    
    // is_empty() - 是否为空
    println!("是否为空: {}", map.is_empty());
    
    // contains_key() - 是否包含键
    println!("包含 'a': {}", map.contains_key("a"));
    
    // remove() - 移除键值对
    let removed = map.remove("a");
    println!("移除 'a': {:?}, 剩余: {:?}", removed, map);
    
    // clear() - 清空
    map.clear();
    println!("清空后: {:?}", map);
}

// ==================== 其他集合 ====================

use std::collections::{HashSet, VecDeque, BTreeMap, BTreeSet};

/// 其他常用集合
pub fn other_collections() {
    println!("\n=== 其他集合 ===");
    
    // HashSet - 无重复值的集合
    let mut set = HashSet::new();
    set.insert(1);
    set.insert(2);
    set.insert(2); // 重复值不会被添加
    println!("HashSet: {:?}", set);
    
    // VecDeque - 双端队列
    let mut deque = VecDeque::new();
    deque.push_back(1);
    deque.push_front(2);
    println!("VecDeque: {:?}", deque);
    
    // BTreeMap - 有序的 Map
    let mut btree = BTreeMap::new();
    btree.insert(3, "c");
    btree.insert(1, "a");
    btree.insert(2, "b");
    println!("BTreeMap: {:?}", btree);
    
    // BTreeSet - 有序的 Set
    let mut btset = BTreeSet::new();
    btset.insert(3);
    btset.insert(1);
    btset.insert(2);
    println!("BTreeSet: {:?}", btset);
}

/// 实际应用示例
pub fn practical_example() {
    println!("\n=== 实际应用: 学生成绩管理 ===");
    
    let mut grades: HashMap<String, Vec<i32>> = HashMap::new();
    
    // 添加成绩
    grades.entry(String::from("Alice"))
        .or_insert(vec![]).push(85);
    grades.entry(String::from("Alice"))
        .or_insert(vec![]).push(90);
    grades.entry(String::from("Bob"))
        .or_insert(vec![]).push(75);
    
    // 计算平均分
    for (name, scores) in &grades {
        let sum: i32 = scores.iter().sum();
        let avg = sum as f64 / scores.len() as f64;
        println!("{}: 成绩 {:?}, 平均分 {:.2}", name, scores, avg);
    }
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust 集合教程                        ║");
    println!("╚════════════════════════════════════════╝");
    
    vector_basics();
    reading_vector_elements();
    iterating_over_vectors();
    storing_multiple_types();
    vector_methods();
    
    string_basics();
    updating_strings();
    string_indexing();
    iterating_over_strings();
    string_methods();
    
    hashmap_basics();
    accessing_hashmap_values();
    hashmap_and_ownership();
    updating_hashmap();
    hashmap_methods();
    
    other_collections();
    practical_example();
    
    println!("\n✅ 集合教程完成！");
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_vector() {
        let v = vec![1, 2, 3];
        assert_eq!(v[0], 1);
        assert_eq!(v.len(), 3);
    }
    
    #[test]
    fn test_string_concat() {
        let s1 = String::from("Hello, ");
        let s2 = String::from("world!");
        let s3 = s1 + &s2;
        assert_eq!(s3, "Hello, world!");
    }
    
    #[test]
    fn test_hashmap() {
        let mut map = HashMap::new();
        map.insert("key", "value");
        assert_eq!(map.get("key"), Some(&"value"));
    }
}

